import axios from 'axios'
import {Message} from 'element-ui'
import NProgress from "nprogress"; // progress bar
import "nprogress/nprogress.css";
import qs from "qs";
import i18n from "@/i18n";
import * as util from "../common/util";
import * as cache from '../common/cache'
import {openLoading,closeLoading} from '../common/loading'

let messageInstance = null
const resetMessage = (options) => {
  if (messageInstance) {
    messageInstance.close()
  }
  messageInstance = Message(options)
}
['error', 'success', 'info', 'warning'].forEach(type => {
  resetMessage[type] = options => {
    if (typeof options === 'string') {
      options = {
        message: options
      }
    }
    options.type = type
    return resetMessage(options)
  }
})



// NProgress Configuration
NProgress.configure({
    showSpinner: false
});

// 超时时间
axios.defaults.timeout = 120000
// 是否运行跨域，跨域请求，允许保存cookie
axios.defaults.withCredentials = true
// 通过本地代理转发请求
axios.defaults.baseURL = '/'

// HTTP request 拦截
axios.interceptors.request.use(
    config => {
        // start progress bar
        NProgress.start()

        // 添加请求头
        // config.headers.add = cache.getLang()
        config.headers['brezze-language'] = cache.getLang() == 'CN' ? 'ZH' : cache.getLang()

        if (!isIgnoreURI(config.url)) {
            // 检查用户信息
            // cache.checkUserInfo()
            // 操作日志参数
            if (config.method.toUpperCase() !== 'GET') {
                const chooseMenuTitle = getMenuTitle()
                // console.log('chooseMenuTitle', chooseMenuTitle)
                if (chooseMenuTitle) {
                    // 当前菜单标题
                    config.headers['module-title'] = encodeURI(
                        JSON.stringify(chooseMenuTitle)
                    )
                }
            }
        }

        // 处理get 请求的数组 springmvc 可以处理
        if (config.method.toUpperCase() == 'GET') {
            config.paramsSerializer = function (params) {
                let paramsData
                if (params) {
                    // 拷贝对象
                    paramsData = JSON.parse(JSON.stringify(params))
                    // console.log(paramsData)
                    // 处理时间范围参数
                    if (paramsData.rangeTime && paramsData.rangeTime.length === 2) {
                        paramsData.rangeTime = paramsData.rangeTime.join(',')
                    }
                }

                return qs.stringify(paramsData, {arrayFormat: "repeat"});
            };
        }
        openLoading()
        return config
    },
    err => {
        return Promise.reject(err)
    }
)


// HTTP response 拦截
axios.interceptors.response.use(
    res => {
        NProgress.done()
        // 如果请求失败主动调用关闭loading组件，防止发送请求后未在catch中主动关闭loading的情况
        closeLoading()
        return res
    },
    err => {
        NProgress.done()
        // 如果请求失败主动调用关闭loading组件，防止发送请求后未在catch中主动关闭loading的情况
        closeLoading()
        return Promise.reject(err)
    }
)


//post API
export function axiosPostAPI(url, params, headers, config) {
    return apiAxios('POST', url, params, headers, config)
}

//get API
export function axiosGetAPI(url, params, headers, config,type) {
    return apiAxios('GET', url, params, headers, config)
}

//put API
export function axiosPutAPI(url, params, headers, config) {
    return apiAxios('PUT', url, params, headers, config)
}

//delete API
export function axiosDeleteAPI(url, params, headers, config,type) {
    return apiAxios('DELETE', url, params, headers, config,type)
}

//delete API
export function axiosPATCHAPI(url, params, headers, config) {
    return apiAxios('PATCH', url, params, headers, config)
}

/**
 * 发送请求
 * @param method    请求方法
 * @param url       请求url
 * @param params    请求参数
 * @param headers   请求头配置
 * @param config    请求配置
 * @returns {Promise<unknown>}
 */
function apiAxios(method, url, params, headers, config,type) {
    const lang = cache.getLang()
    const platformId = cache.get('platformId')
    const serveId = cache.get('serveId')

    const defaultHeader = {
        'content-Type': 'application/json;charset=UTF-8;multipart/form-data;',
        'lang': lang ? lang : '',
        'serve-id': serveId ? parseInt(serveId) : '1',
        'platform-id': platformId ? parseInt(platformId) : '1',
        'device-id': util.getUUID(),
    }
    const defaultConfig = {
        method: method,
        url: url,
        data: method === 'POST' || method === 'PUT' || method === 'PATCH' || (method === 'DELETE' && type ) ? params : null,
        params: method === 'GET' || (method === 'DELETE' && !type ) ? params : null,
        headers: {...defaultHeader, ...headers},
    }

    return new Promise((resolve, reject) => {
        if (params) {
            params = filterNull(params)
        }
        axios({...defaultConfig, ...config})
            .then(function (res) {
                // console.log('res', res)
                if (res.data.code === 200) {
                    resolve(res.data)
                } else {
                    resolve(res.data)
                }
            })
            .catch(function (error) {
                // console.log(error);
                if (error.response != undefined) {
                    const status = error.response.status;
                    const statusText = error.response.statusText;
                    if (status == 401) {
                        resetMessage.error(i18n.t('m.Login_expire'))
                        util.toLogin()
                    }
                    if (status == 503) {
                        resetMessage.error(statusText)
                    }
                    if (status == 502) {
                        resetMessage.error(statusText)
                    }
                    if (status == 403) {
                        resetMessage.error(statusText)
                    }
                    if (status == 404) {
                        resetMessage.error(statusText)
                    }
                    if (status == 405) {
                        resetMessage.error(statusText)
                    }
                    if (status == 400) {
                        resetMessage.error(statusText)
                    }
                }
            })
    })
}

function toType(obj) {
    return {}.toString
        .call(obj)
        .match(/\s([a-zA-Z]+)/)[1]
        .toLowerCase()
}

// 参数过滤函数
function filterNull(o) {
    for (const key in o) {
        if (o[key] === null) {
            delete o[key]
        }
        if (toType(o[key]) === 'string') {
            o[key] = o[key].trim()
        } else if (toType(o[key]) === 'object') {
            o[key] = filterNull(o[key])
        } else if (toType(o[key]) === 'array') {
            o[key] = filterNull(o[key])
        }
    }
    return o
}


// 获取菜单栏标题
function getMenuTitle() {
    let title = null
    const menuList = cache.get('menuList')
    if (menuList && menuList.length > 0) {
        menuList.forEach(item => {
            item.childMenu.forEach(childItem => {
                title = childItem.title
            })
        })
    }
    return title
}

// 免登录校验uri
const ignoreURI = ['/manage/login', '/manage/common']

// 是否存在忽略URI
function isIgnoreURI(uri) {
    for (let i = 0; i < ignoreURI.length; i++) {
        if (uri.startsWith(ignoreURI[i])) {
            return true
        }
    }
    return false
}
